package de.koller.aframe.util.misc;

import de.koller.aframe.util.math.interpolation.CubicInterpolation;
import de.koller.aframe.util.math.interpolation.LinearInterpolation;
import de.koller.oceanFramework.gl.util.ImagePreview;
import de.koller.oceanFramework.util.ColorIntUtil;
import java.awt.image.BufferedImage;

public class ColorGradient {

	public static int linear( float k, int... colors ) {
		if( k >= 1 ) k = .99999f;
		if( k < 0 ) k = 0;
		
		k *= colors.length-1;
		
		float zk = k % 1f;
		int dk = (int)Math.floor( k );
		
		return getLinearColor( zk, colors[dk], colors[dk+1] );
	}

	public static int cubic( float k, int... colors ) {
		if( k >= 1 ) k = .99999f;
		if( k < 0 ) k = 0;
		
		k *= colors.length-1;
		
		float zk = k % 1f;
		int dk = (int)Math.floor( k );
		
		return getCubicColor( zk, colors[dk], colors[dk+1] );
	}
	
	public static int getCubicColor( float k, int colorB, int colorA ) {
		float a = CubicInterpolation.cubic( k, ColorIntUtil.getAValue( colorA ),
											   ColorIntUtil.getAValue( colorB ),
											   ColorIntUtil.getAValue( colorA ),
											   ColorIntUtil.getAValue( colorB ) );
		float r = CubicInterpolation.cubic( k, ColorIntUtil.getRValue( colorA ),
											   ColorIntUtil.getRValue( colorB ),
											   ColorIntUtil.getRValue( colorA ),
											   ColorIntUtil.getRValue( colorB ) );
		float g = CubicInterpolation.cubic( k, ColorIntUtil.getGValue( colorA ),
											   ColorIntUtil.getGValue( colorB ),
											   ColorIntUtil.getGValue( colorA ),
											   ColorIntUtil.getGValue( colorB ) );
		float b = CubicInterpolation.cubic( k, ColorIntUtil.getBValue( colorA ),
											   ColorIntUtil.getBValue( colorB ),
											   ColorIntUtil.getBValue( colorA ),
											   ColorIntUtil.getBValue( colorB ) );
		
		return ColorIntUtil.getIntColor( (int)a, (int)r, (int)g, (int)b );
	}
	
	public static int getLinearColor( float k, int colorB, int colorA ) {
		float a = LinearInterpolation.linear( k, ColorIntUtil.getAValue( colorB ),
												 ColorIntUtil.getAValue( colorA ) );
		float r = LinearInterpolation.linear( k, ColorIntUtil.getRValue( colorB ),
												 ColorIntUtil.getRValue( colorA ) );
		float g = LinearInterpolation.linear( k, ColorIntUtil.getGValue( colorB ),
												 ColorIntUtil.getGValue( colorA ) );
		float b = LinearInterpolation.linear( k, ColorIntUtil.getBValue( colorB ),
												 ColorIntUtil.getBValue( colorA ) );

		return ColorIntUtil.getIntColor( (int)a, (int)r, (int)g, (int)b );
	}
	
	public static void main( String[] args ) {
		BufferedImage i = new BufferedImage( 1200, 2, BufferedImage.TYPE_INT_ARGB );
		for( int x = 0; x < 1200; x++ ) {
			i.setRGB( x, 0, linear( 1f/1200f*x, 
					0xff_0000ff,
					0xff_00ffff,
					0xff_00ff00,
					0xff_ffff00,
					0xff_ff0000 ) );
			
			i.setRGB( x, 1, cubic( 1f/1200f*x, 
					0xff_0000ff,
					0xff_00ffff,
					0xff_00ff00,
					0xff_ffff00,
					0xff_ff0000 ) );
		}
		
		ImagePreview.showImage( i, 1200, 200 );
		
		
	}
	
}
